namespace SilverSea.Untilities
{
    using System;
    using System.Runtime.CompilerServices;
    using System.Threading;

    public sealed class Parallel
    {
        private AutoResetEvent[] autoResetEvent_0;
        private ForLoopBody forLoopBody_0;
        private static int int_0 = Environment.ProcessorCount;
        private int int_1;
        private int int_2;
        private ManualResetEvent[] manualResetEvent_0;
        private static object object_0 = new object();
        private static volatile Parallel parallel_0 = null;
        private Thread[] thread_0;

        private Parallel()
        {
        }

        public static void For(int start, int stop, ForLoopBody loopBody)
        {
            lock (object_0)
            {
                Parallel parallel = smethod_0();
                parallel.int_1 = start - 1;
                parallel.int_2 = stop;
                parallel.forLoopBody_0 = loopBody;
                for (int i = 0; i < int_0; i++)
                {
                    parallel.manualResetEvent_0[i].Reset();
                    parallel.autoResetEvent_0[i].Set();
                }
                for (int j = 0; j < int_0; j++)
                {
                    parallel.manualResetEvent_0[j].WaitOne();
                }
            }
        }

        private void method_0()
        {
            this.autoResetEvent_0 = new AutoResetEvent[int_0];
            this.manualResetEvent_0 = new ManualResetEvent[int_0];
            this.thread_0 = new Thread[int_0];
            for (int i = 0; i < int_0; i++)
            {
                this.autoResetEvent_0[i] = new AutoResetEvent(false);
                this.manualResetEvent_0[i] = new ManualResetEvent(true);
                this.thread_0[i] = new Thread(new ParameterizedThreadStart(this.method_2));
                this.thread_0[i].Name = "View100.Parallel";
                this.thread_0[i].IsBackground = true;
                this.thread_0[i].Start(i);
            }
        }

        private void method_1()
        {
            this.forLoopBody_0 = null;
            int index = 0;
            int length = this.thread_0.Length;
            while (index < length)
            {
                this.autoResetEvent_0[index].Set();
                this.thread_0[index].Join();
                this.autoResetEvent_0[index].Close();
                this.manualResetEvent_0[index].Close();
                index++;
            }
            this.autoResetEvent_0 = null;
            this.manualResetEvent_0 = null;
            this.thread_0 = null;
        }

        private void method_2(object object_1)
        {
            int index = (int) object_1;
            int num2 = 0;
        Label_003A:
            this.autoResetEvent_0[index].WaitOne();
            if (this.forLoopBody_0 == null)
            {
                return;
            }
        Label_0017:
            num2 = Interlocked.Increment(ref this.int_1);
            if (num2 < this.int_2)
            {
                this.forLoopBody_0(num2);
                goto Label_0017;
            }
            this.manualResetEvent_0[index].Set();
            goto Label_003A;
        }

        private static Parallel smethod_0()
        {
            if (parallel_0 == null)
            {
                parallel_0 = new Parallel();
                parallel_0.method_0();
            }
            else if (parallel_0.thread_0.Length != int_0)
            {
                parallel_0.method_1();
                parallel_0.method_0();
            }
            return parallel_0;
        }

        public static int ThreadsCount
        {
            get
            {
                return int_0;
            }
            set
            {
                lock (object_0)
                {
                    int_0 = Math.Max(1, value);
                }
            }
        }

        public delegate void ForLoopBody(int index);
    }
}

